package vues

import scala.swing._
import event._
import scala.actors._
import Actor._
import java.awt.Color
import java.awt.Font







  


/*------------------------------------------------------------------------*/
/**
 * Classe qui sert de GUI pour notre process Explorer
 */
object LinuxProcessExplorerMainView extends SimpleGUIApplication {

  
  
  def top = MainFrame
  
  val mPresenteur :presenteurs.MainPresenteur=new presenteurs.MainPresenteur
  var valuesTable :Table=null
  var strUnite:String 	="KB"
  var intUnite:Int      =1
  var intRafPeriod      =1000
  
  /*@start MENU 1*/
  var cmiZombieProcessItem :CheckMenuItem=null
  var cmiSystemProcessItem :CheckMenuItem=null
  var cmiGroupeProcessItem :CheckMenuItem=null
  var cmiStatsProcessItem 	:CheckMenuItem=null
  
  /*@end*/
  
  /*@start MENU 2*/
  var rdiFrequenceHaute	  :RadioMenuItem=null
  var rdiFrequenceMoyenne :RadioMenuItem=null
  var rdiFrequenceBasse   :RadioMenuItem=null
  var rdiUniteKb 	  	  :RadioMenuItem=null
  var rdiUniteGb          :RadioMenuItem=null
  var rdiUniteMb          :RadioMenuItem=null
  /*@end*/
  
  
  
  /**
   * 
   */
  def getInitalValues: Array[Array[Any]] ={
    val emptyMatrix = new Array[Array[Any]](200,domaine.ProcessStatus.ColumnCount)
    emptyMatrix
  }
  
  /**
   * La frame principale de la GUI
   */
  val MainFrame= new MainFrame
  {
  
    title = Utils.Constantes.TITLE
    preferredSize = new Dimension(800, 600)
    val dateLabel = new Label { 
      font= new Font("Serif", Font.BOLD, 14)
      }
    
    /*Permet de fixer l'unité de mesure de la consommation mémoire*/
    def getUnit()={
      " (KB)"
    }
    
    
    valuesTable = new Table(
    		getInitalValues,
    		
    		Array(	
    				domaine.ProcessStatus.User,
    				domaine.ProcessStatus.PID,
    				domaine.ProcessStatus.Image,
    				domaine.ProcessStatus.Vm_Data,
    				domaine.ProcessStatus.Vm_Swap,
    				domaine.ProcessStatus.Vm_Rss,
    				domaine.ProcessStatus.Vm_Exe,
    				domaine.ProcessStatus.Vm_Stk,
    				domaine.ProcessStatus.Vm_Peak,
    				domaine.ProcessStatus.Cpu_Time+" ms",
    				domaine.ProcessStatus.Cpu_Taux+ " %",
    				domaine.ProcessStatus.Threads,
    				domaine.ProcessStatus.State))
	    		{
	      
	    		  showGrid  = true
	    		  gridColor = Color.BLUE
	    		  foreground= Color.BLACK
	    		  font = new Font("MS SANS Serif", Font.CENTER_BASELINE, 12)
	    		  
	    		}

    /*--------------------------------------------------------------------------*/
    /* Setting the header font style*/
    valuesTable.peer.getTableHeader().setFont(new Font("Serif", Font.BOLD, 12))
    
    /*--------------------------------------------------------------------------*/
    /*Adding buttons to interaction*/
    val updateButton 	= new Button 	
    {text = Utils.Constantes.LABEL_UPDATE;name=Utils.Constantes.BTN_UPDATE}
    val killButton      = new Button    
    {text = Utils.Constantes.LABEL_KILL;name=Utils.Constantes.BTN_KILL}
    val processExpLabel = new Label 	
    {text = Utils.Constantes.LABEL_PROCESS+intRafPeriod/1000+ "s"}
    
    /*-------------------------------------------------------------------------*/
    /*@start Menu Fichier*/
    menuBar = new MenuBar {     
	contents += new Menu("Fichier") {         
			contents += new MenuItem(Action("Nouvelle tâche")
			{
			    mPresenteur.startNewTask("bash")
			})
			
			contents += new MenuItem(Action("Quitter") 
			    { 
					mPresenteur.exitApp()
			    }) 
			}      
	/*@end*/
	
	/*-------------------------------------------------------------------------*/
	/*@start Menu options*/
	cmiZombieProcessItem = new CheckMenuItem("Afficher les processus zombie")
	cmiSystemProcessItem = new CheckMenuItem("Afficher les processus système")            
	cmiGroupeProcessItem = new CheckMenuItem("Afficher les processus par groupe")      
	cmiStatsProcessItem  = new CheckMenuItem("Afficher les statistiques") 
	val mutexTypeProcess = new ButtonGroup(cmiGroupeProcessItem,cmiSystemProcessItem,cmiZombieProcessItem)
    contents += new Menu("Options"){
	  
	  contents ++= mutexTypeProcess.buttons
	
	  contents += new Separator        
	  contents += cmiStatsProcessItem
	  }      
	/*@end*/
	
	
	/*--------------------------------------------------------------------------*/
    /*@start Menu affichage */
    rdiFrequenceHaute 	= new RadioMenuItem("Haute"){name="rbfh"}
    rdiFrequenceMoyenne = new RadioMenuItem("Moyenne"){name="rbfm"}
    rdiFrequenceBasse 	= new RadioMenuItem("Basse"){name="rbfb"}
    val mutexFrequence  = new ButtonGroup(rdiFrequenceBasse,rdiFrequenceHaute,rdiFrequenceMoyenne)		  
    
    rdiUniteKb = new RadioMenuItem("KB"){name ="rbuk"}
    rdiUniteMb = new RadioMenuItem("MB"){name ="rbum"}
    rdiUniteGb = new RadioMenuItem("GB"){name ="rbug"}
    val mutexUnite = new ButtonGroup(rdiUniteKb,rdiUniteMb,rdiUniteGb)		  
    
	contents += new Menu("Affichage"){
    		  
    		  contents += new MenuItem("Fréquence rafraichissement")
			  contents += new Separator        
			  
    		  contents ++=mutexFrequence.buttons
    		  contents += new Separator        
			  
			  contents += new MenuItem("Unité")
    		  contents += new Separator        
			  contents ++=mutexUnite.buttons
    	}
    
    /*@start A propos*/
    contents += new Menu("?"){
    		  contents += new MenuItem(Action("A propos") { 
    		    println(title)
    		    mPresenteur.aPropos()
    		    }) 
    		  contents += new MenuItem(Action("Aides")    { println(title) }) 
    		  
			  }
    }
    /*@end*/
    
    contents = new BoxPanel(Orientation.Vertical)  
    {
        contents += dateLabel
        contents += valuesTable
        val tab = new MyPanel
        contents += tab
        
        var sp = new BoxPanel(Orientation.Vertical)  
        {
          contents+= new ScrollPane(valuesTable)
          contents+= new FlowPanel
          {
            contents+= updateButton
            contents+= killButton
            contents+= processExpLabel
            
          }
        }

        tab.pageTab1.content = sp
      }

      /*@start abonement aux buttons*/
      listenTo(updateButton)
      listenTo(killButton)
      listenTo(rdiFrequenceHaute)
      listenTo(rdiFrequenceBasse)
      listenTo(rdiFrequenceMoyenne)
      listenTo(rdiUniteGb)
      listenTo(rdiUniteKb)
      listenTo(rdiUniteMb)
      /*@end*/
      
      /*----------------------------------------------------------------*/
      /*@start reactions des buttons*/
      reactions +=
        {
          case ButtonClicked(button) =>
            /*Ici mettre l'action qui sera déclanchée lors du clique*/
            button.name match
            {
              case Utils.Constantes.BTN_UPDATE =>
              
              case Utils.Constantes.BTN_KILL   => 
                {
                  
                    val rows=valuesTable.selection.rows
                    
                    val pids=valuesTable.model.getValueAt(0,0)
                	mPresenteur.killProcess(1111)
                	
                }
                
              //#region dynamic params
              case "rbfh" => intRafPeriod=1000 
              				 looper.continue()
              
              case "rbfm" => intRafPeriod=5000
              				 looper.continue()

              case "rbfb" => intRafPeriod=10000 
              				 looper.continue()
              
              case "rbum" => strUnite="Mb"
            	  			 intUnite=1024
              
              case "rbuk" => strUnite="Kb" 
            	  			 intUnite=1
              
              case "rbug" => strUnite="Gb" 
            	  			 intUnite=1024*1024
              //#endregion
            }
            Console.println("Btn clicked : "+button.name)
            //button.enabled = false
            uiUpdater ! "ok"
            

        }
    /*@end*/
	
	/*@start Acteur qui permet de mettre à jour la vue*/
	val uiUpdater = new Actor 
	{
	  def act = {
	    loop
	    {
	      react{
	        case "ok" => 
	          					
	          					val format = "dd/MM/yy H:mm:ss"; 
	          					val formater = new java.text.SimpleDateFormat( format ); 
	          					val date = new java.util.Date(); 
 
	        					dateLabel.text= Utils.Constantes.LABEL_DATE+formater.format( date )
	          					processExpLabel.text=Utils.Constantes.LABEL_PROCESS+intRafPeriod/1000+"s"
            
	        					updateTable("ok")
	          					updateButton.enabled = true
	          					killButton.enabled 	 = true
	      }
	    }
	  }
	  
	  override def scheduler() = new SingleThreadedScheduler
	}
	
	uiUpdater.start()
	/*@end*/
	
	/*@start acteur qui calcul la source de données*/
	val looper = new Actor 
	{
	  def act = {
	    
	    while(true){
	      Thread.sleep(intRafPeriod)
	      mPresenteur.getDataSource()
	      uiUpdater ! "ok"
	    }
	  }
	}
	looper.start()
	/*@end*/

	/*@start mise à jour de la table des processus*/
	def updateTable(value :String)
	{
	      //Console.println("Hello from update panel with row count = "+ valuesTable.rowCount)
	      mPresenteur.actualiser()
	}
  }
  
}